// 1、创建项目 启动服务器
const express = require('express');
const app = express();
// 表单验证模块
const Joi = require('joi');
// 导入解析Token的中间件 和 生成token的密钥配置文件
const expressJWT = require('express-jwt');
const config = require('./schema/config');
// 2、配置cors跨域
const cors = require('cors');
app.use(cors());
// 3、配置解析表单数据的中间件 
// 注意 这个中间件只能解析application/x-www-form-urlencoded格式的表单数据
app.use(express.urlencoded({ extended: false }));
// app.use(express.json());
// 客户端发送过来的还有JSONP格式的 还有 Formdata格式的 TEXT格式 JSON格式等等 对应的解析中间件？？
// json 格式 app.use(express.json());
// multer模块用于解析 FormData格式数据
// 托管服务器中uploads路径下的静态资源  便于外界用户可以访问到 同源 避免跨域
app.use('/uploads', express.static('./uploads'));

// 优化  封装服务器响应错误信息的函数 并设置为全局中间件
app.use((req, res, next) => {
    res.cc = (err, status = 1) => {
        err = err instanceof Error ? err.message : err
        res.send({
            status,
            message: err
        });
    };
    next();
})

// 解析token字符串 expressJWT({secret:密钥}) url路径中含有/api的请求不予解析
app.use(expressJWT({ secret: config.secretKey }).unless({ path: [/^\/api\//] }));

// 注册用户路由模块
// 导入自定义路由模块
const userRouter = require('./router/user.js');
// 添加api访问前缀
app.use('/api', userRouter);

// 注册个人中心路由模块
// 导入自定义路由模块
const userInfoRouter = require('./router/userinfo');
// 添加my访问前缀  这是个有权限的接口
app.use('/my', userInfoRouter);

// 导入并注册文章分类管理路由模块
const articleCate = require('./router/articleCate');
// 注册路由 并添加访问前缀
app.use('/my/article', articleCate);

// 导入并注册文章管理路由模块a
const articles = require('./router/articles');
app.use('/my/article', articles)

//  错误级别中间件
app.use(function(err, req, res, next) {
    //  捕获 Joi 参数校验失败时的错误
    if (err instanceof Joi.ValidationError) return res.cc(err);
    // 捕获JWT身份认证失败的错误
    if (err.name === 'UnauthorizedError') return res.cc('身认证失败！');
    // 捕获未知错误
    res.cc(err);
})

app.listen(3007, () => {
    console.log('Api server running at http://127.0.0.1:3007 \n ----------------服务已启动---------------');
});